package Entity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;

import Controllers.GlobalData;
import Controllers.GenericToolsForController.PDFfile;
import Exception.ICMException;
import ServerOperation.ReportPDFWriter;

public class Report implements Serializable 
{
	
	/**
	 *  This entity class represent the reports of the system. many classes extends it.
	 */
	private static final long serialVersionUID = 1L;
	protected Worker creator;
	protected int reportId;
	protected File file;
	protected String comment;
	protected PDFfile pdfFile;
	protected ReportType type;
	protected Date dateOfCreation;

	public ReportType getType() {
		return this.type;
	}
	
	/**
	 * Empty constructor
	 */
	
	public Report()
	{
		
	}
	
	/**
	 * Common use constructor. creator is the user that initiated the report. reportId is it key in the DB. File is the file holding pointer to where we save the file itself.
	 * We allow comment to be saved for general purpose. pdf file holds the document version of the report.
	 * @param creator
	 * @param reportId
	 * @param file
	 * @param comment
	 * @param pdfFile
	 */
	public Report(Worker creator, int reportId, File file,String comment,PDFfile pdfFile) {
		super();
		this.creator = creator;
		this.reportId = reportId;
		this.file = file;
		this.comment= comment;
		this.pdfFile = pdfFile;
	}
	
	public Report(Worker creator, String comment,PDFfile pdfFile,Date dateOfCreation,ReportType type) {
		super();
		this.creator = creator;
		this.dateOfCreation = dateOfCreation;
		this.comment= comment;
		this.pdfFile = pdfFile;
		this.type = type;
	}
	public Report(int reportId,Worker creator, String comment,PDFfile pdfFile,Date dateOfCreation,ReportType type) {
		super();
		this.reportId = reportId;
		this.creator = creator;
		this.dateOfCreation = dateOfCreation;
		this.comment= comment;
		this.pdfFile = pdfFile;
		this.type = type;
	}
	
	/**
	 * returns the date the report was created.
	 * @return
	 */
	public Date getDateOfCreation() {
		return dateOfCreation;
	}
	/**
	 * 
	 * @param dateOfCreation
	 */
	public void setDateOfCreation(Date dateOfCreation) {
		this.dateOfCreation = dateOfCreation;
	}
	public void setType(ReportType type) {
		this.type = type;
	}
	public PDFfile getPdfFile() {
		return pdfFile;
	}
	public void setPdfFile(PDFfile pdfFile) {
		this.pdfFile = pdfFile;
	}
	public String getComment() {
		return comment;
	}
	public void setComment(String comment) {
		this.comment = comment;
	}
	public Worker getCreator() {
		return creator;
	}
	public void setCreator(Worker creator) {
		this.creator = creator;
	}
	public int getReportId() {
		return reportId;
	}
	public void setReportId(int reportId) {
		this.reportId = reportId;
	}
	public File getFile() {
		return file;
	}
	public void setFile(File file) {
		this.file = file;
	}
	
	public int addToDb() throws ICMException
	{
	
			int opCode = -1;
			if (this.getType() == ReportType.EVALUATION)
			{
				opCode=5001;  // copy the evaluation file to server and create new record in report table
			}
			else
			{
				if (this.getType() == ReportType.TESTING)
				{
					opCode=5002;
				}
				else
				{
					throw new ICMException("Could not resolve opcode");
				}
			}
			Message msg = null;
			Message AnswerMessage = null;
			msg = new Message(opCode, GlobalData.MESSAGE_ID(),this);
		
			System.out.println("msg :" + msg.getMessageID() + " " + msg.getOpCode());
			if (msg != null)
			{
			try 
			{
				GlobalData.client.sendToServer(msg);
				System.out.println("msg sent");

				
				try 
				{
					Thread.sleep(500);
				} 
				catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				while (true)
				{
					if (GlobalData.client.isRecivedMessage()==true)
					{
						AnswerMessage = GlobalData.client.getAnsweredMessage(msg);
					    if (AnswerMessage!=null)
					  	      break;
					}	
				}
			} 
			catch (IOException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			if (AnswerMessage.getDataGram() != null && AnswerMessage.getDataGram() instanceof Integer)
				return((Integer)AnswerMessage.getDataGram());	
	}
			else
			{
				throw new ICMException("expected integer back from creating report");
			}
			return -1;
	
	}
	
	
	public File buildTestingFailureReport(Request request,String strDescription){
		
		  String strDateHeadline = "Generated On: ";
	      String strDescriptionHeadlin = "Description of the testing failure : ";
	      
	 
		  this.type = ReportType.TESTING;
		  this.setCreator(GlobalData.worker);
		  this.dateOfCreation = Calendar.getInstance().getTime();
		
		 String strHeadline = "Tesing Failure Report for Examiner: ";
	     String currentDir = System.getProperty("user.dir");
			String path = currentDir+"\\";
			File dir=new File(path);
			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creates new dir : "+path);
			}
			path = (path + (this.creator.getUsername().replaceAll(" ", "_").replaceAll(":", "_"))+"\\");
			 dir=new File(path);
			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
			}
			path = path +creator.getId() +"\\";
			 dir=new File(path);

			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
			}
			path = path +request.getRequestId()+"\\";
			 dir=new File(path);

			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
			}
			String startDateOfCreation = new SimpleDateFormat("yyyy-MM-dd").format(dateOfCreation);
			path+="TestingFailureReport-"+startDateOfCreation+".pdf";
			
			ReportPDFWriter writer = new ReportPDFWriter(path);
			writer.addLogo();
		
				writer.writeUnderline(strHeadline);
				writer.write(creator.toString()+"\n\n");
				writer.writeUnderline(strDateHeadline);
				writer.write(startDateOfCreation+"\n" );
				writer.writeUnderline(strDescriptionHeadlin);
				writer.write(strDescription+"\n\n");
			    writer.close();
			    return new File(path);
	      
		
		
}
	
	public File buildEvaluationReport(Request request, String strLocation, String strDescription,
			String strDesiredChange, String strRisk, int daysEstimate) throws IOException 
	{
	    
		  String strDateHeadline = "Generated On: ";
	      String strLocationHeadline = "Location of the proposed change:";
	      String strDescriptionHeadlin = "Description of the proposed change:";
	      String strProposedChangeHeadline = "Desired Change: " ;
	      String strRisksHeadline = "Risks and Limitations: ";
	      String strEstimatedTimeHeadline = "Estimated Time for completion: ";
		this.type = ReportType.EVALUATION;
		this.setCreator(GlobalData.worker);
		this.dateOfCreation = Calendar.getInstance().getTime();
		
		 String strHeadline = "Evaluation Report for Evaluator: ";
	     String strHeadlineReval = "Re-Evaluation (More details needed) Report for Evaluator: ";
	     String currentDir = System.getProperty("user.dir");
			String path = currentDir+"\\";
			File dir=new File(path);
			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
			}
			path = (path + this.creator+"\\");
			 dir=new File(path);
			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
	
			}
			path = path +request.getRequestId()+"\\";
			 dir=new File(path);

			if(! dir.exists())
			{
				dir.mkdir();
				System.out.println("Creats new dir : "+path);
			}
			String startDateOfCreation = new SimpleDateFormat("yyyy-MM-dd").format(dateOfCreation);
			path+="EvaluationReport-"+startDateOfCreation+".pdf";
			
			ReportPDFWriter writer = new ReportPDFWriter(path);
			writer.addLogo();
		/*	if (this.notes != null)	
			{
				writer.writeTitle("Evaluation Report appends:");
		  	    writer.writeUnderline(strHeadlineReval);
		  	    writer.write(creator.toString()+"\n\n");
			    writer.writeUnderline("The evlautor added the following details: "+"\n\n");
				writer.write(notes+ " \n\n");
				writer.writeTitle("Prevoius reports: \n\n");
				notes = null;
			}*/
				writer.writeUnderline(strHeadline);
				writer.write(creator.toString()+"\n\n");
				writer.writeUnderline(strDateHeadline);
				writer.write(startDateOfCreation+"\n" );
				writer.writeUnderline(strLocationHeadline);
				writer.write(strLocation+"\n\n");
				writer.writeUnderline(strDescriptionHeadlin);
				writer.write(strDescription+"\n\n");
				writer.writeUnderline(strProposedChangeHeadline);
				writer.write(strDesiredChange+"\n\n");
				writer.writeUnderline(strRisksHeadline);
				writer.write(strRisk+"\n");
				writer.writeUnderline(strEstimatedTimeHeadline);
				writer.write(daysEstimate+"  days\n\n");            
			    writer.close();
			    return new File(path);
	      
	}	
	
	
	public File buildreEvaluationReport(Request request, String addedNotes)
	{    
			String strDateHeadline = "Generated On: ";
			this.type = ReportType.EVALUATION;
			this.setCreator(GlobalData.worker);
			this.dateOfCreation = Calendar.getInstance().getTime();
			
			 String strHeadline = "Evaluation Report for Evaluator: ";
		     String strHeadlineReval = "Re-Evaluation (More details needed) Report for Evaluator: ";
		     String currentDir = System.getProperty("user.dir");
		     String path = currentDir+"\\";
				File dir=new File(path);
				if(! dir.exists())
				{
					dir.mkdir();
					System.out.println("Creats new dir : "+path);
				}
				path = (path + this.creator+"\\");
				 dir=new File(path);
				if(! dir.exists())
				{
					dir.mkdir();
					System.out.println("Creats new dir : "+path);
		
				}
				path = path +request.getRequestId()+"\\";
				 dir=new File(path);

				if(! dir.exists())
				{
					dir.mkdir();
					System.out.println("Creats new dir : "+path);
				}
				path+= "ReavluationReport.PDF";
				ReportPDFWriter writer = new ReportPDFWriter(path);
				writer.addLogo();
				if (addedNotes != null)	
				{
					writer.writeTitle("Evaluation Report appends:");
			  	    writer.writeUnderline(strHeadlineReval);
			  	    writer.write(creator.toString()+"\n\n");
				    writer.writeUnderline("The evlautor added the following details: "+"\n\n");
					writer.write(addedNotes+ " \n\n");
				}
				writer.close();
				return new File(path);
				
			}
	}
	
	
	
